﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using ReLogic.OS;

namespace Terraria.Utilities
{
	// Token: 0x020000C6 RID: 198
	public static class CrashDump
	{
		// Token: 0x06000ABE RID: 2750 RVA: 0x0000B81A File Offset: 0x00009A1A
		public static bool WriteException(CrashDump.Options options, string outputDirectory = ".")
		{
			return CrashDump.Write(options, CrashDump.ExceptionInfo.Present, outputDirectory);
		}

		// Token: 0x06000ABF RID: 2751 RVA: 0x0000B824 File Offset: 0x00009A24
		public static bool Write(CrashDump.Options options, string outputDirectory = ".")
		{
			return CrashDump.Write(options, CrashDump.ExceptionInfo.None, outputDirectory);
		}

		// Token: 0x06000AC0 RID: 2752 RVA: 0x003E70E0 File Offset: 0x003E52E0
		private static string CreateDumpName()
		{
			DateTime dateTime = DateTime.Now.ToLocalTime();
			return string.Format("{0}_{1}_{2}_{3}.dmp", new object[]
			{
				"Terraria",
				Main.versionNumber,
				dateTime.ToString("MM-dd-yy_HH-mm-ss-ffff", CultureInfo.InvariantCulture),
				Thread.CurrentThread.ManagedThreadId
			});
		}

		// Token: 0x06000AC1 RID: 2753 RVA: 0x003E7144 File Offset: 0x003E5344
		private static bool Write(CrashDump.Options options, CrashDump.ExceptionInfo exceptionInfo, string outputDirectory)
		{
			if (!Platform.IsWindows)
			{
				return false;
			}
			string path = Path.Combine(outputDirectory, CrashDump.CreateDumpName());
			if (!Directory.Exists(outputDirectory))
			{
				Directory.CreateDirectory(outputDirectory);
			}
			bool result;
			using (FileStream fileStream = File.Create(path))
			{
				result = CrashDump.Write(fileStream.SafeFileHandle, options, exceptionInfo);
			}
			return result;
		}

		// Token: 0x06000AC2 RID: 2754 RVA: 0x003E71A8 File Offset: 0x003E53A8
		private static bool Write(SafeHandle fileHandle, CrashDump.Options options, CrashDump.ExceptionInfo exceptionInfo)
		{
			if (!Platform.IsWindows)
			{
				return false;
			}
			Process currentProcess = Process.GetCurrentProcess();
			IntPtr handle = currentProcess.Handle;
			uint id = (uint)currentProcess.Id;
			CrashDump.MiniDumpExceptionInformation miniDumpExceptionInformation;
			miniDumpExceptionInformation.ThreadId = CrashDump.GetCurrentThreadId();
			miniDumpExceptionInformation.ClientPointers = false;
			miniDumpExceptionInformation.ExceptionPointers = IntPtr.Zero;
			if (exceptionInfo == CrashDump.ExceptionInfo.Present)
			{
				miniDumpExceptionInformation.ExceptionPointers = Marshal.GetExceptionPointers();
			}
			bool result;
			if (miniDumpExceptionInformation.ExceptionPointers == IntPtr.Zero)
			{
				result = CrashDump.MiniDumpWriteDump(handle, id, fileHandle, (uint)options, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
			}
			else
			{
				result = CrashDump.MiniDumpWriteDump(handle, id, fileHandle, (uint)options, ref miniDumpExceptionInformation, IntPtr.Zero, IntPtr.Zero);
			}
			return result;
		}

		// Token: 0x06000AC3 RID: 2755
		[DllImport("dbghelp.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
		private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, ref CrashDump.MiniDumpExceptionInformation expParam, IntPtr userStreamParam, IntPtr callbackParam);

		// Token: 0x06000AC4 RID: 2756
		[DllImport("dbghelp.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
		private static extern bool MiniDumpWriteDump(IntPtr hProcess, uint processId, SafeHandle hFile, uint dumpType, IntPtr expParam, IntPtr userStreamParam, IntPtr callbackParam);

		// Token: 0x06000AC5 RID: 2757
		[DllImport("kernel32.dll", ExactSpelling = true)]
		private static extern uint GetCurrentThreadId();

		// Token: 0x020000C7 RID: 199
		[Flags]
		public enum Options : uint
		{
			// Token: 0x04000F06 RID: 3846
			Normal = 0u,
			// Token: 0x04000F07 RID: 3847
			WithDataSegs = 1u,
			// Token: 0x04000F08 RID: 3848
			WithFullMemory = 2u,
			// Token: 0x04000F09 RID: 3849
			WithHandleData = 4u,
			// Token: 0x04000F0A RID: 3850
			FilterMemory = 8u,
			// Token: 0x04000F0B RID: 3851
			ScanMemory = 16u,
			// Token: 0x04000F0C RID: 3852
			WithUnloadedModules = 32u,
			// Token: 0x04000F0D RID: 3853
			WithIndirectlyReferencedMemory = 64u,
			// Token: 0x04000F0E RID: 3854
			FilterModulePaths = 128u,
			// Token: 0x04000F0F RID: 3855
			WithProcessThreadData = 256u,
			// Token: 0x04000F10 RID: 3856
			WithPrivateReadWriteMemory = 512u,
			// Token: 0x04000F11 RID: 3857
			WithoutOptionalData = 1024u,
			// Token: 0x04000F12 RID: 3858
			WithFullMemoryInfo = 2048u,
			// Token: 0x04000F13 RID: 3859
			WithThreadInfo = 4096u,
			// Token: 0x04000F14 RID: 3860
			WithCodeSegs = 8192u,
			// Token: 0x04000F15 RID: 3861
			WithoutAuxiliaryState = 16384u,
			// Token: 0x04000F16 RID: 3862
			WithFullAuxiliaryState = 32768u,
			// Token: 0x04000F17 RID: 3863
			WithPrivateWriteCopyMemory = 65536u,
			// Token: 0x04000F18 RID: 3864
			IgnoreInaccessibleMemory = 131072u,
			// Token: 0x04000F19 RID: 3865
			ValidTypeFlags = 262143u
		}

		// Token: 0x020000C8 RID: 200
		private enum ExceptionInfo
		{
			// Token: 0x04000F1B RID: 3867
			None,
			// Token: 0x04000F1C RID: 3868
			Present
		}

		// Token: 0x020000C9 RID: 201
		[StructLayout(LayoutKind.Sequential, Pack = 4)]
		private struct MiniDumpExceptionInformation
		{
			// Token: 0x04000F1D RID: 3869
			public uint ThreadId;

			// Token: 0x04000F1E RID: 3870
			public IntPtr ExceptionPointers;

			// Token: 0x04000F1F RID: 3871
			[MarshalAs(UnmanagedType.Bool)]
			public bool ClientPointers;
		}
	}
}
